package com.ctg.behavior.calc.impala.transfer.usergroups;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.ctg.behavior.calc.common.CtSQLParam;
import com.ctg.behavior.calc.impala.report.uesrgroups.CtUGUSSequenceReport;
import com.ctg.behavior.calc.impala.transfer.CtFilterTransfer;
import com.ctg.behavior.calc.impala.transfer.CtTimeRestrictTransfer;
import com.ctg.behavior.calc.utils.CtCalcSQLUtils;
import com.ctg.behavior.common.calc.CtCalc;
import com.ctg.behavior.common.calc.CtCalcStep;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class CtUGUSSequenceTransfer extends CtFilterTransfer {

	@Autowired
	private CtTimeRestrictTransfer timeRestrictTransfer;

	/******************************************************
	 * @apiNote:
	 */
	@Override
	public String doTransfer(CtCalc calcObject, CtSQLParam sqlParam) {
		if (!(calcObject instanceof CtUGUSSequenceReport)) {
			log.warn("calcObject is not CtUGUSSequenceReport, class={}", calcObject.getClass());
			log.warn("calcObject: {}", JSON.toJSON(calcObject));
			return "";
		}

		CtUGUSSequenceReport usSequence = (CtUGUSSequenceReport) calcObject;
		log.info("CalcBody={}", JSON.toJSONString(usSequence));

		String transferredSQL = null;
		List<CtCalcStep> steps = usSequence.getSteps();
		for (int index = 0; index < steps.size(); index++) {
			transferredSQL = this.transferOneStep(index, usSequence, transferredSQL, sqlParam);
			log.info("step index={}, transferredSQL={}", index, transferredSQL);
		}

		log.info("CalcSQL={}", transferredSQL);

		return transferredSQL;
	}

	public String transferOneStep(Integer transferredStepIndex, CtUGUSSequenceReport usSequence, String lastStepSQL, CtSQLParam sqlParam) {

		// 别名
		String stepAlias = "step" + transferredStepIndex;
		String joinAlias = "stepj" + transferredStepIndex;
		// transferredStep
		CtCalcStep transferredStep = usSequence.getSteps().get(transferredStepIndex);
		log.info("CalcBody-Step{},={}", transferredStepIndex, JSON.toJSONString(usSequence));

		StringBuilder impalaSQL = new StringBuilder();
		// impalaSQL.append(" SELECT device_id AS deviceId, min(event_date) AS event_date, min(event_time) AS event_time ");
		impalaSQL.append(" SELECT ").append(stepAlias).append(".user_id AS userId ");
		impalaSQL.append(" , min(").append(stepAlias).append(".event_date) AS event_date ");
		impalaSQL.append(" , min(").append(stepAlias).append(".event_time) AS event_time ");
		impalaSQL.append(" FROM a_event_parquet_").append(usSequence.getAppId()).append(" ");
		// 增加别名
		impalaSQL.append(" ").append(stepAlias).append(" ");
		// 1. 是否有上一步骤的SQL, 有则需要使用JOIN
		if (!StringUtils.isEmpty(lastStepSQL)) {
			impalaSQL.append(" JOIN ");
			impalaSQL.append(" ( ").append(lastStepSQL).append(" ) ").append(joinAlias).append(" ");
			impalaSQL.append(" ON  ").append(stepAlias).append(".user_id = ").append(joinAlias).append(".userId ");
		}
		impalaSQL.append(" WHERE 1=1 ");
		// 2. 筛选条件 - event (事件标识)
		{
			impalaSQL.append(" AND ").append(stepAlias).append(".event = '");
			impalaSQL.append(transferredStep.getEventId()).append("' ");
		}
		// 3. 筛选条件 - Filter
		{
			CtSQLParam conditionAliasParam = CtSQLParam.createAliasParam(stepAlias);
			String sqlCondtions = super.doTransfer(transferredStep.getFilter(), conditionAliasParam);
			if (!CtCalcSQLUtils.isEmptyCondtions(sqlCondtions)) {
				impalaSQL.append(" AND ").append(sqlCondtions);
			}
		}
		// 4. 时间限制 - timeRestrict
		{
			CtSQLParam conditionAliasParam = CtSQLParam.createAliasParam(stepAlias);
			String sqlCondtions = timeRestrictTransfer.doTransfer(usSequence.getTimeRestrict(), conditionAliasParam);
			if (!CtCalcSQLUtils.isEmptyCondtions(sqlCondtions)) {
				impalaSQL.append(" AND ").append(sqlCondtions);
			}
		}
		// 5. 是否有上一步骤的SQL, 有则需求把实现步骤时间先后顺序
		if (!StringUtils.isEmpty(lastStepSQL)) {
			impalaSQL.append(" AND ( ");

			impalaSQL.append(" ( ");
			impalaSQL.append(stepAlias).append(".event_date = ").append(joinAlias).append(".event_date ");
			impalaSQL.append(" AND ");
			impalaSQL.append(stepAlias).append(".event_time >= ").append(joinAlias).append(".event_time ");
			impalaSQL.append(" ) ");

			impalaSQL.append(" OR ");

			impalaSQL.append(stepAlias).append(".event_date > ").append(joinAlias).append(".event_date ");

			impalaSQL.append(" ) ");
		}

		// impalaSQL.append(" GROUP BY device_id ");
		// 增加别名
		impalaSQL.append(" GROUP BY ").append(stepAlias).append(".user_id ");

		String retSQL = impalaSQL.toString();
		log.info("CalcSQL-Step{},={}", transferredStepIndex, retSQL);

		return retSQL;

	}

}
